//+------------------------------------------------------------------+
//|                                                     SignalAO.mqh |
//|                             Copyright 2000-2025, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#include <Expert/ExpertSignal.h>    // 专家顾问信号基类（提供信号生成框架）

// wizard description start（MQL5 策略向导描述，用于识别类信息与参数）
//+------------------------------------------------------------------+
//| 类功能描述                                                       |
//| Title=基于动量振荡器（Awesome Oscillator）的交易信号              |
//| Type=SignalAdvanced                                              |
//| Name=Awesome Oscillator                                          |
//| ShortName=AO                                                     |
//| Class=CSignalAO                                                  |
//| Page=signal_ao                                                   |
//+------------------------------------------------------------------+
// wizard description end

//+------------------------------------------------------------------+
//| CSignalAO 类：基于动量振荡器（AO）的交易信号生成器                |
//| 核心能力：继承自 CExpertSignal，通过调用 AO 指标（基于价格中位价的动量指标）， |
//|           识别4类经典 AO 信号形态（柱体颜色、碟形、过零、背离），生成多空信号， |
//|           支持通过“信号权重”调整不同形态的优先级，适配趋势反转与动量延续行情   |
//| 核心逻辑：AO 指标=（5期 SMA 中位价）-（34期 SMA 中位价），差值>0为“绿柱”（看涨）， |
//|           <0为“红柱”（看跌）；通过柱体颜色变化、与零轴交叉、指标-价格背离判断信号 |
//| 适用场景：中短线趋势反转与动量交易（AO 擅长捕捉市场动量变化），适合外汇、期货等 |
//|           品种，尤其适合在震荡行情末期捕捉趋势启动，需与趋势指标（如均线）配合   |
//+------------------------------------------------------------------+
class CSignalAO : public CExpertSignal
  {
protected:
   // 核心组件与参数（保护，子类可访问）
   CiAO              m_ao;             // AO 指标对象（封装动量振荡器的计算与数据读取）
   // 市场形态信号权重（0-100，值越大信号优先级越高，默认配置突出背离与过零信号）
   int               m_pattern_0;      // 形态0权重：首根分析K线符合预期颜色（如多单需首根为绿柱）
   int               m_pattern_1;      // 形态1权重：“碟形”信号（AO 柱体形成“碗状”反转形态）
   int               m_pattern_2;      // 形态2权重：“过零”信号（AO 指标线从负转正/正转负穿越零轴）
   int               m_pattern_3;      // 形态3权重：“背离”信号（AO 指标与价格形成顶/底背离）
   // 极值分析辅助变量（用于背离信号判断，存储指标与价格的极值关系）
   double            m_extr_osc[10];   // AO 指标极值数组（存储最近10个指标极值点）
   double            m_extr_pr[10];    // 对应价格极值数组（存储指标极值点对应的价格极值）
   int               m_extr_pos[10];   // 极值位置数组（存储极值点对应的K线偏移量，单位：根）
   uint              m_extr_map;       // 极值关系位图（用二进制位记录指标与价格极值的相对关系，辅助背离判断）

public:
   //----------------------------------------------------------------
   // 构造与析构函数
   //----------------------------------------------------------------
   /**
    * @brief 构造函数：初始化 AO 信号生成器
    * @details 1. 初始化 AO 指标对象，设置默认信号权重（形态0=30，形态1=20，形态2=70，形态3=90）；
    *          2. 启用价格序列（最高价+最低价，因 AO 指标基于中位价=（高+低）/2 计算）；
    *          3. 初始化极值分析数组（指标极值、价格极值、位置）及位图；
    *          4. 继承父类 CExpertSignal 的信号框架初始化
    */
                     CSignalAO(void);

   /**
    * @brief 析构函数：清理 AO 信号生成器资源
    * @details 释放 AO 指标对象及极值数组占用的内存，依赖父类析构逻辑完成信号框架资源清理
    */
                    ~CSignalAO(void);

   //----------------------------------------------------------------
   // 信号权重配置：修改不同市场形态的信号强度（外部调用接口）
   //----------------------------------------------------------------
   /**
    * @brief 设置形态0（首根K线颜色符合预期）的信号权重
    * @param value [in] 权重值（0-100，建议20-40，值越大越重视首根K线的颜色验证）
    */
   void              Pattern_0(int value);

   /**
    * @brief 设置形态1（碟形反转）的信号权重
    * @param value [in] 权重值（0-100，建议10-30，值越大越重视碟形反转形态）
    */
   void              Pattern_1(int value);

   /**
    * @brief 设置形态2（过零交叉）的信号权重
    * @param value [in] 权重值（0-100，建议60-80，值越大越重视 AO 穿越零轴的趋势信号）
    */
   void              Pattern_2(int value);

   /**
    * @brief 设置形态3（指标-价格背离）的信号权重
    * @param value [in] 权重值（0-100，建议80-100，值越大越重视背离带来的反转信号）
    */
   void              Pattern_3(int value);

   //----------------------------------------------------------------
   // 指标初始化：创建并注册 AO 指标（信号生成的前提）
   //----------------------------------------------------------------
   /**
    * @brief 初始化 AO 指标及信号所需的价格序列数据
    * @param indicators [in] 指标集合对象（用于管理所有策略用到的指标，如 AO、均线等）
    * @return bool - 初始化结果：true=成功（AO 指标创建+注册到指标集合），false=失败
    * @note 调用流程：
    *       1. 先调用父类 InitIndicators() 完成基础信号框架与价格序列初始化；
    *       2. 调用内部 InitAO() 方法创建 AO 指标并绑定当前交易品种与周期；
    *       3. 若指标创建失败（如品种无效），返回 false 并终止信号生成
    */
   virtual bool      InitIndicators(CIndicators *indicators);

   //----------------------------------------------------------------
   // 信号判断核心方法：生成多空信号权重（策略决策依据）
   //----------------------------------------------------------------
   /**
    * @brief 判断当前市场是否满足多单（买入）开仓条件，返回信号权重
    * @return int - 多单信号权重（0-100，0=无信号，值越大信号越强烈）
    * @note 核心判断逻辑（基于 AO 指标形态）：
    *       1. 形态0验证：首根分析K线 DiffAO>0（绿柱，看涨倾向），不满足则返回0；
    *       2. 形态2（过零信号）：若首根绿柱 AO>0，且前一根 AO<0 → 上穿零轴，返回形态2权重；
    *       3. 形态1（碟形信号）：若首根绿柱 AO>0，且前一根 DiffAO<0 → 形成碗状底，返回形态1权重；
    *       4. 形态3（背离信号）：若首根绿柱 AO<0，且前一根 DiffAO<0 → 调用 ExtStateAO() 分析极值，
    *          若指标与价格形成底背离（价格创新低，AO 不创新低），返回形态3权重；
    *       5. 优先级：形态3 > 形态2 > 形态1 > 形态0（满足高优先级则直接返回，不叠加）
    */
   virtual int       LongCondition(void);

   /**
    * @brief 判断当前市场是否满足空单（卖出）开仓条件，返回信号权重
    * @return int - 空单信号权重（0-100，0=无信号，值越大信号越强烈）
    * @note 核心判断逻辑（与多单相反，基于 AO 指标形态）：
    *       1. 形态0验证：首根分析K线 DiffAO<0（红柱，看跌倾向），不满足则返回0；
    *       2. 形态2（过零信号）：若首根红柱 AO<0，且前一根 AO>0 → 下穿零轴，返回形态2权重；
    *       3. 形态1（碟形信号）：若首根红柱 AO<0，且前一根 DiffAO>0 → 形成碗状顶，返回形态1权重；
    *       4. 形态3（背离信号）：若首根红柱 AO>0，且前一根 DiffAO>0 → 调用 ExtStateAO() 分析极值，
    *          若指标与价格形成顶背离（价格创新高，AO 不创新高），返回形态3权重；
    *       5. 优先级：形态3 > 形态2 > 形态1 > 形态0（满足高优先级则直接返回，不叠加）
    */
   virtual int       ShortCondition(void);

protected:
   //----------------------------------------------------------------
   // 内部辅助方法：AO 指标初始化（仅内部调用）
   //----------------------------------------------------------------
   /**
    * @brief 创建并初始化 AO 指标（绑定品种、周期，注册到指标集合）
    * @param indicators [in] 指标集合对象（用于管理 AO 指标）
    * @return bool - 初始化结果：true=成功（指标创建+参数配置完成），false=失败
    * @note 内部流程：
    *       1. 检查指标集合指针有效性；
    *       2. 将 AO 指标对象（m_ao）添加到指标集合；
    *       3. 调用 m_ao.Create() 绑定当前交易品种（m_symbol.Name()）与周期（m_period）；
    *       4. AO 指标默认参数为（5期 SMA 中位价 - 34期 SMA 中位价），无需额外配置；
    *       5. 若添加或创建失败，输出错误日志并返回 false
    */
   bool              InitAO(CIndicators *indicators);

   //----------------------------------------------------------------
   // 数据读取与状态分析：快捷获取指标数据及判断状态（保护，子类可直接调用）
   //----------------------------------------------------------------
   /**
    * @brief 获取指定索引的 AO 指标原始值
    * @param ind [in] 索引（0=当前K线，1=前一根K线，以此类推）
    * @return double - AO 指标值（正数=绿柱，负数=红柱，零=无动量）
    */
   double            AO(int ind);

   /**
    * @brief 计算指定索引K线的 AO 指标差值（当前K线 - 前一根K线，即柱体颜色判断依据）
    * @param ind [in] 索引（0=当前K线，1=前一根K线，以此类推）
    * @return double - AO 差值（>0=绿柱，<0=红柱，=0=柱体颜色不变）
    * @note 差值符号直接决定 AO 指标柱体颜色，是形态0、形态1判断的核心数据
    */
   double            DiffAO(int ind);

   /**
    * @brief 分析指定索引K线的 AO 指标趋势状态（连续同色柱体数量）
    * @param ind [in] 索引（分析起点K线）
    * @return int - 趋势状态值（正数=连续绿柱数量，负数=连续红柱数量，0=无连续趋势）
    * @note 例如返回 3 表示从 ind 开始连续3根绿柱，返回 -2 表示连续2根红柱，用于判断趋势强度
    */
   int               StateAO(int ind);

   /**
    * @brief 扩展分析 AO 指标与价格的极值关系（生成背离判断所需的极值位图）
    * @param ind [in] 索引（分析起点K线）
    * @return bool - 分析结果：true=成功（生成极值数组与位图），false=失败（数据不足）
    * @note 核心逻辑：
    *       1. 从 ind 开始遍历K线，通过 StateAO() 识别 AO 指标的极值点（连续同色柱体的转折点）；
    *       2. 记录每个指标极值点对应的价格极值（指标低点对应价格低点，指标高点对应价格高点）；
    *       3. 用 m_extr_map 位图记录相邻极值点的关系（如价格创新低但指标未创新低 → 标记为底背离）；
    *       4. 结果用于形态3（背离信号）的判断，是 AO 信号中最复杂的分析逻辑
    */
   bool              ExtStateAO(int ind);
  };
//+------------------------------------------------------------------+